import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.pqc.crypto.crystals.dilithium.*;
import org.bouncycastle.util.encoders.Hex;
import java.security.SecureRandom;


//CRYSTALS-Dilithium (ML-DSA)
public class JcaDilithiumExample {
private static String pretty(String hex) {
    return hex.replaceAll("(.{64})", "$1\n");
}
    public static void main(String[] args) {
        SecureRandom random = new SecureRandom();

        // 1. 选择安全参数（Dilithium2, Dilithium3, Dilithium5）
        DilithiumParameters params = DilithiumParameters.dilithium2;

        // 2. 生成密钥对
        DilithiumKeyPairGenerator keyPairGen = new DilithiumKeyPairGenerator();
        keyPairGen.init(new DilithiumKeyGenerationParameters(random, params));
        var keyPair = keyPairGen.generateKeyPair();

        DilithiumPublicKeyParameters pubKey = (DilithiumPublicKeyParameters) keyPair.getPublic();
        DilithiumPrivateKeyParameters privKey = (DilithiumPrivateKeyParameters) keyPair.getPrivate();

        // 3. 取原始字节并转 HEX
        byte[] pubBytes  = pubKey.getEncoded();   // BC 1.78+ 已提供
        byte[] privBytes = privKey.getEncoded();  // BC 1.78+ 已提供

        System.out.println("Public key  (hex):\n" + pretty(Hex.toHexString(pubBytes)));
        System.out.println("Private key (hex):\n" + pretty(Hex.toHexString(privBytes)));

        // 3. 准备要签名的消息
        byte[] message = "这是一条需要抗量子签名的重要消息。".getBytes();

        // 4. 签名
        DilithiumSigner signer = new DilithiumSigner();
        signer.init(true, privKey); // true 表示用于签名
        byte[] signature = signer.generateSignature(message);

        System.out.println("签名长度: " + signature.length + " 字节");

        // 5. 验证签名
        signer.init(false, pubKey); // false 表示用于验证
        boolean isValid = signer.verifySignature(message, signature);

        System.out.println("签名验证结果: " + isValid);

        // 6. 尝试验证一个被篡改的消息
        byte[] tamperedMessage = "这是一条被篡改的需要抗量子签名的重要消息。".getBytes();
        boolean isTamperedValid = signer.verifySignature(tamperedMessage, signature);
        System.out.println("篡改后消息的验证结果: " + isTamperedValid);
    }
}



